package com.xuzimian.globaldemo.spring.springmvc.config;

import com.xuzimian.globaldemo.spring.springmvc.filter.MyFilter;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;


/**
 * 在 Servlet 3.0 环境下，Servlet 容器会在 classpath 下搜索实现了 javax.servlet.ServletContainerInitializer 接口的任何类，
 * 找到之后用它来初始化 Servlet 容器。
 *
 * Spring 实现了以上接口，实现类叫做 SpringServletContainerInitializer， 它会依次搜寻实现了 WebApplicationInitializer的任何类，
 * 并委派这个类实现配置。之后，Spring 3.2 开始引入一个简易的 WebApplicationInitializer 实现类，
 * 这就是 AbstractAnnotationConfigDispatcherServletInitializer。
 *
 * @author xzm
 */
public class AnnotationWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
/**
 * 启用请去掉注释
 *  extends AbstractAnnotationConfigDispatcherServletInitializer
 */
{

    /**
     * 启用请去掉注释
     * 根容器:返回的配置类定义了Spring应用根容器中的beans
     * 注意：上面配置的ComponentScan 会在spring 根容器中。但是不会将扫描到的controller 等springmvc 组件
     * @Override
     */
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{RootConfig.class};
    }

    /**
     * 启用请去掉注释
     * Spring mvc容器:返回的配置类定义了Spring MVC应用容器中的beans
     *  注意：上面配置的ComponentScan 会在spring mvc 容器中，这里配置扫描 spring mvc 相关的组件，如Controller
     * @Override
     */
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{WebConfig.class};
    }

    /**
     * 启用请去掉注释
     *
     * @Override
     */
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }


    /**
     * 返回的所有Filter都会映射到DispatcherServlet上
     * @return
     */
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[]{ new MyFilter()};
    }

    /**
     * 为了使用Bean scope = request 和 session，需要注册RequestContextListener 监听器。
     * 以下是javaconfig方式，还可以在web.xml中配置。而Spring-boot 在WebMvcAutoConfiguration
     * 类中进行了自动配置，所以无需配置。
     * @param servletContext
     */
    @Override
    protected void registerContextLoaderListener(ServletContext servletContext) {
        super.registerContextLoaderListener(servletContext);
        servletContext.addListener(new RequestContextListener());
    }

    /***
     * 在Servlet容器中注册后自定义一些操作，如开启文件上传功能，
     * 则可重写通过AbstractAnnotationConfigDispatcherServletInitializer 的customizeRegistration() 来实现
     *
     * ------------------------------------------------------------------------------------------------
     * 或向ioc容器添加一个MultipartResolver 的bean来实现上传文件控制，如：WebConfig.class中的multipartResolver 方法。
     *
     * @param registration
     */
    /**
     * 启用请去掉注释
     *
     * @Override
     */
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        registration.setMultipartConfig(
                new MultipartConfigElement("/tmp/spittr/uploads", 2097152, 4194304, 0));
    }


}